feat: improve mui styles as figma - sponsor services#239
feat: improve mui styles as figma - sponsor services#239priscila-moneo wants to merge 1 commit intomainfrom
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
📝 WalkthroughWalkthroughThis PR enhances the UI component library with internationalization infrastructure changes and refactors AuthButton into a dropdown menu. It updates i18n merge strategy, adds new translation keys, rewrites AuthButton from a toggle to a MUI dropdown, propagates profile data through NavBar, extends CompanyInputV2 with translated messages and improved filtering, and polishes table and dropdown styling. ChangesUI Component Enhancement & i18n Integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/inputs/company-input-v2.js`:
- Line 134: The InputLabelProps is forcing shrink:false whenever disableShrink
is true, which causes label overlap when a value is present; update the
InputLabelProps usage in company-input-v2.js (the line that sets
InputLabelProps={...}) to conditionally set shrink: false only when
disableShrink is true AND there is no value (e.g., InputLabelProps={
disableShrink ? { shrink: !value } : undefined } or equivalent using the
component's value/inputValue variable) so the label will still shrink when a
value exists.
In `@src/components/mui/AuthButton/index.js`:
- Around line 58-74: The IconButton used as the user menu trigger (IconButton
with AccountCircleIcon, ref anchorRef, onClick openMenu, state menuOpen) lacks
an accessible name; add an appropriate aria-label (e.g., "Open user menu" or
"User account") to the IconButton so screen readers can identify the control,
keeping existing aria-controls/aria-expanded/aria-haspopup props intact and
using a concise, localized label matching the button's purpose.
- Around line 128-155: The Settings and Profile MenuItem entries in AuthButton
only call closeMenu and lack callbacks, so they close the menu but perform no
action; add two optional props (e.g., onSettings and onProfile) to the
AuthButton component signature and propTypes/TS types, then wire them into the
respective MenuItem onClick handlers (call closeMenu() and then call
props.onSettings() or props.onProfile() if provided) so clicking those items
triggers the supplied callbacks; update any places that render AuthButton to
pass handlers where needed and ensure default behavior remains safe when
callbacks are undefined.
In `@src/components/mui/NavBar/index.js`:
- Line 47: The NavBar is passing a dead prop picture={profilePic} into
AuthButton; either remove this unused prop from NavBar (and from NavBar's
props/destructuring and any related propTypes/TS types) or restore support by
updating AuthButton to accept a picture prop and render the profile image.
Locate the picture usage in the NavBar JSX (picture={profilePic}), remove that
attribute and clean up NavBar's profilePic handling, or alternatively add a
picture parameter to AuthButton (and its render logic) to preserve the profile
image flow.
In `@src/components/mui/table/mui-table.js`:
- Around line 189-190: The archive action column is constrained by tableLayout:
"fixed" plus hard 80px width/minWidth/maxWidth on the TableCell, causing
translated "archive/unarchive" labels to clip; update the TableCell used when
onArchive is present (and the other action cells referenced around lines with
onArchive/onDelete) to remove the maxWidth constraint and give a larger,
flexible size (e.g., set width:auto and a more generous minWidth like 120px) or
drop tableLayout: "fixed" for action columns so the content can expand; change
the TableCell props in the mui table component (the TableCell instances rendered
when onArchive and similar action flags are truthy) accordingly and apply the
same fix to the other action column occurrences noted in the comment.
- Around line 225-231: The IconButton elements (e.g., the one with
data-testid="action-edit" that calls onEdit(row) and the similar delete button)
have undersized click targets due to size="small" plus sx={{ padding: 0 }};
update these buttons to provide an accessible hit target by removing the zero
padding and/or the small size and instead apply a minimum padding (e.g., theme
spacing >= 1 or 8px) or use size="medium" so the clickable area meets touch
target guidelines; keep the same icons and handlers (EditIcon, onEdit(row),
delete handler) and adjust the sx styling for both the edit and delete
IconButton instances mentioned in the diff.
In `@src/i18n/i18n.js`:
- Line 2: The import uses a deep path ("i18n-react/dist/i18n-react") which is
fragile; replace the deep import with the package entrypoint by changing the
import of T (import T from "i18n-react/dist/i18n-react") to import from
"i18n-react" instead, and run a repo-wide search/replace for the same deep path
to update the ~45 other files (e.g., occurrences in CartButton, AuthButton,
company-input-v2) so all modules import from "i18n-react" consistently; after
updating, run the build/linter/tests to verify no remaining deep-path
references.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a41a8060-8748-482a-8236-846183def046
📒 Files selected for processing (9)
src/components/inputs/company-input-v2.jssrc/components/mui/AuthButton/index.jssrc/components/mui/AuthButton/styles.module.scsssrc/components/mui/CartButton/index.jssrc/components/mui/NavBar/index.jssrc/components/mui/formik-inputs/mui-formik-dropdown-checkbox.jssrc/components/mui/table/mui-table.jssrc/i18n/en.jsonsrc/i18n/i18n.js
| error={error} | ||
| margin="normal" | ||
| InputLabelProps={{ shrink: disableShrink }} | ||
| InputLabelProps={disableShrink ? { shrink: false } : undefined} |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
MUI Autocomplete v6 InputLabelProps shrink false value overlap behavior
💡 Result:
In MUI (Material-UI) v6, the Autocomplete component renders its input via the renderInput prop, typically a TextField. The TextField's label shrink behavior is controlled by the InputLabelProps={{ shrink: false }} passed to the TextField inside renderInput.[1][2][3] Setting shrink: false forces the InputLabel to remain in its expanded (non-shrunk) position inside the input field, regardless of whether the Autocomplete has a value, is focused, or has an inputValue.[4][5][6] This can cause the label text to visually overlap with the selected value or input text, as the label does not move to the top border position.[7][8][9][10] This overlap occurs because: - Normally, the label automatically shrinks (via data-shrink="true") when there is a value, focus, or certain input states, positioning it above the input border.[5] - With shrink: false, it stays overlaid on the input content.[11] - In Autocomplete, the internal inputValue may initially be empty even with a value prop, exacerbating animation/jump issues, though recent v6 fixes (e.g., #45734, #46047) address shrink animation regressions for controlled values and multiple mode with empty arrays.[12][13][14][15][16] Example causing overlap: <Autocomplete value={someValue} renderInput={(params) => ( <TextField {...params} label="Label" InputLabelProps={{ shrink: false }} // Forces non-shrunk state /> )} /> The label will overlap the displayed getOptionLabel(someValue) or input text.[8][17] To avoid overlap while keeping the label expanded initially: - Use dynamic shrink: InputLabelProps={{ shrink: !!value || focused }} with state for focus.[18] - Or let MUI auto-handle shrink (omit shrink: false), accepting automatic shrinking on value/focus.[5] - CSS hacks like adjusting top exist but are brittle.[7] Official docs note shrink state isn't always perfect (e.g., number/date inputs), recommending manual shrink override only when needed.[5]
Citations:
- 1: https://v6.mui.com/material-ui/api/autocomplete
- 2: https://v6.mui.com/material-ui/api/autocomplete/
- 3: https://mui.com/api/autocomplete/
- 4: https://mui.com/material-ui/api/input-label/
- 5: https://v6.mui.com/material-ui/react-text-field
- 6: https://v6.mui.com/material-ui/api/input-label
- 7: Autocomplete + textfield leads to the label overlapping mui/material-ui#44798
- 8: [autocomplete] Label of the TextField shrinks when there is an option selected while the label of a normal filled TextField doesn't mui/material-ui#36548
- 9: TextField with select: Label overlaps selected value mui/material-ui#13013
- 10: Label overlapping input mui/material-ui#13186
- 11: Label won't 🐛 shrink in text field mui/material-ui#23173
- 12: https://github.com/mui/material-ui/blob/v6.4.2/CHANGELOG.md
- 13: [material-ui][Autocomplete] Prevent shrink animation in controlled Autocomplete when initial
valueis provided (@imadx) mui/material-ui#45735 - 14: [autocomplete] Prevent shrink animation in controlled Autocomplete when initial
valueis provided mui/material-ui#45734 - 15: [autocomplete] Fix label shrink issue when
renderValueis used with empty array in multiple mode mui/material-ui#46047 - 16: [autocomplete] Label is shrinked when providing an empty array as a
valueto Autocomplete when usingmultipleandrenderValuemui/material-ui#46037 - 17: https://mui.com/material-ui/react-autocomplete/
- 18: https://stackoverflow.com/questions/72796172/material-ui-autocomplete-with-inputlabelprops-shrink-true-in-custom-theme
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '125,145p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 910
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '1,50p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 2284
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '110,140p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 1195
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '60,85p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 1131
Prevent label overlap when disableShrink is enabled.
Passing { shrink: false } unconditionally overrides MUI Autocomplete's label management. When a value is present and disableShrink is true, the label stays in its resting position and overlaps the displayed text. Apply shrink: false only when there is no value:
Suggested fix
- InputLabelProps={disableShrink ? { shrink: false } : undefined}
+ InputLabelProps={disableShrink && !value ? { shrink: false } : undefined}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| InputLabelProps={disableShrink ? { shrink: false } : undefined} | |
| InputLabelProps={disableShrink && !value ? { shrink: false } : undefined} |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/inputs/company-input-v2.js` at line 134, The InputLabelProps
is forcing shrink:false whenever disableShrink is true, which causes label
overlap when a value is present; update the InputLabelProps usage in
company-input-v2.js (the line that sets InputLabelProps={...}) to conditionally
set shrink: false only when disableShrink is true AND there is no value (e.g.,
InputLabelProps={ disableShrink ? { shrink: !value } : undefined } or equivalent
using the component's value/inputValue variable) so the label will still shrink
when a value exists.
| <IconButton | ||
| aria-controls={menuOpen ? "user-menu" : undefined} | ||
| aria-expanded={menuOpen ? "true" : undefined} | ||
| aria-haspopup="true" | ||
| onClick={openMenu} | ||
| size="medium" | ||
| data-testid="user-menu-button" | ||
| sx={{ | ||
| color: theme.palette.text.primary, | ||
| p: 0, | ||
| width: 28, | ||
| height: 28 | ||
| }} | ||
| ref={anchorRef} | ||
| > | ||
| <AccountCircleIcon sx={{fontSize: 28}}/> | ||
| </IconButton> |
There was a problem hiding this comment.
IconButton is missing aria-label — screen readers cannot identify it.
The button contains only an icon with no text. Without an aria-label, assistive technologies announce it as an unlabeled button.
♿ Proposed fix
<IconButton
aria-controls={menuOpen ? "user-menu" : undefined}
aria-expanded={menuOpen ? "true" : undefined}
aria-haspopup="true"
+ aria-label="Open user menu"
onClick={openMenu}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <IconButton | |
| aria-controls={menuOpen ? "user-menu" : undefined} | |
| aria-expanded={menuOpen ? "true" : undefined} | |
| aria-haspopup="true" | |
| onClick={openMenu} | |
| size="medium" | |
| data-testid="user-menu-button" | |
| sx={{ | |
| color: theme.palette.text.primary, | |
| p: 0, | |
| width: 28, | |
| height: 28 | |
| }} | |
| ref={anchorRef} | |
| > | |
| <AccountCircleIcon sx={{fontSize: 28}}/> | |
| </IconButton> | |
| <IconButton | |
| aria-controls={menuOpen ? "user-menu" : undefined} | |
| aria-expanded={menuOpen ? "true" : undefined} | |
| aria-haspopup="true" | |
| aria-label="Open user menu" | |
| onClick={openMenu} | |
| size="medium" | |
| data-testid="user-menu-button" | |
| sx={{ | |
| color: theme.palette.text.primary, | |
| p: 0, | |
| width: 28, | |
| height: 28 | |
| }} | |
| ref={anchorRef} | |
| > | |
| <AccountCircleIcon sx={{fontSize: 28}}/> | |
| </IconButton> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/mui/AuthButton/index.js` around lines 58 - 74, The IconButton
used as the user menu trigger (IconButton with AccountCircleIcon, ref anchorRef,
onClick openMenu, state menuOpen) lacks an accessible name; add an appropriate
aria-label (e.g., "Open user menu" or "User account") to the IconButton so
screen readers can identify the control, keeping existing
aria-controls/aria-expanded/aria-haspopup props intact and using a concise,
localized label matching the button's purpose.
| <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}> | ||
| <ListItemIcon sx={{minWidth: 32, color: menuIconColor}}> | ||
| <SettingsIcon sx={{fontSize: 24}}/> | ||
| </ListItemIcon> | ||
| <ListItemText | ||
| primary={T.translate("general.settings")} | ||
| primaryTypographyProps={{ | ||
| sx: { | ||
| fontSize: menuFontSize, | ||
| color: theme.palette.text.primary | ||
| } | ||
| }} | ||
| /> | ||
| </MenuItem> | ||
| <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}> | ||
| <ListItemIcon sx={{minWidth: 32, color: menuIconColor}}> | ||
| <PersonIcon sx={{fontSize: 24}}/> | ||
| </ListItemIcon> | ||
| <ListItemText | ||
| primary={T.translate("general.profile")} | ||
| primaryTypographyProps={{ | ||
| sx: { | ||
| fontSize: menuFontSize, | ||
| color: theme.palette.text.primary | ||
| } | ||
| }} | ||
| /> | ||
| </MenuItem> |
There was a problem hiding this comment.
Settings and Profile menu items are non-functional — missing callback props.
Both MenuItem elements only call closeMenu(). There is no onSettings or onProfile (or equivalent) prop on AuthButton, so clicking either item closes the dropdown and does nothing else. These appear as functional options to the user but have no effect.
Add callback props and wire them up:
🐛 Proposed fix
const AuthButton = ({
isLoggedUser,
doLogin,
initLogOut,
profileEmail,
- profileName
+ profileName,
+ onSettings,
+ onProfile
}) => {- <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}>
+ <MenuItem onClick={() => { closeMenu(); onSettings?.(); }} sx={{py: 1.5, px: 3, gap: 1.5}}>
...
</MenuItem>
- <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}>
+ <MenuItem onClick={() => { closeMenu(); onProfile?.(); }} sx={{py: 1.5, px: 3, gap: 1.5}}>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/mui/AuthButton/index.js` around lines 128 - 155, The Settings
and Profile MenuItem entries in AuthButton only call closeMenu and lack
callbacks, so they close the menu but perform no action; add two optional props
(e.g., onSettings and onProfile) to the AuthButton component signature and
propTypes/TS types, then wire them into the respective MenuItem onClick handlers
(call closeMenu() and then call props.onSettings() or props.onProfile() if
provided) so clicking those items triggers the supplied callbacks; update any
places that render AuthButton to pass handlers where needed and ensure default
behavior remains safe when callbacks are undefined.
| @@ -37,6 +45,8 @@ const NavBar = ({title, profilePic, isLoggedUser, onClickLogin, initLogOut}) => | |||
| <AuthButton | |||
| isLoggedUser={isLoggedUser} | |||
| picture={profilePic} | |||
There was a problem hiding this comment.
Dead prop: picture is no longer consumed by AuthButton.
AuthButton was refactored to remove the picture prop entirely. Passing picture={profilePic} here has no effect and will confuse future maintainers. Additionally, callers of NavBar who previously relied on profilePic to render a profile image will silently lose that visual without any indication.
Either remove the prop pass-through or preserve the profile picture in the new AuthButton design.
🛠️ Minimal cleanup (if picture display is not being restored)
<AuthButton
isLoggedUser={isLoggedUser}
- picture={profilePic}
profileEmail={profileEmail}
profileName={profileName}
doLogin={onClickLogin}
initLogOut={initLogOut}
/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| picture={profilePic} | |
| <AuthButton | |
| isLoggedUser={isLoggedUser} | |
| profileEmail={profileEmail} | |
| profileName={profileName} | |
| doLogin={onClickLogin} | |
| initLogOut={initLogOut} | |
| /> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/mui/NavBar/index.js` at line 47, The NavBar is passing a dead
prop picture={profilePic} into AuthButton; either remove this unused prop from
NavBar (and from NavBar's props/destructuring and any related propTypes/TS
types) or restore support by updating AuthButton to accept a picture prop and
render the profile image. Locate the picture usage in the NavBar JSX
(picture={profilePic}), remove that attribute and clean up NavBar's profilePic
handling, or alternatively add a picture parameter to AuthButton (and its render
logic) to preserve the profile image flow.
| {onArchive && <TableCell sx={{width: 80, minWidth: 80, maxWidth: 80}}/>} | ||
| {onDelete && <TableCell sx={{width: 40, minWidth: 40, maxWidth: 40}}/>} |
There was a problem hiding this comment.
Archive action column is too constrained for translated labels.
With tableLayout: "fixed" plus width/minWidth/maxWidth: 80, the archive/unarchive text is prone to clipping in non-English locales. This is an i18n UX break on a primary action.
Suggested fix
- {onArchive && <TableCell sx={{width: 80, minWidth: 80, maxWidth: 80}}/>}
+ {onArchive && <TableCell sx={{minWidth: 120}}/>}
...
- sx={getCellSx(row, {width: 80, minWidth: 80, maxWidth: 80})}
+ sx={getCellSx(row, {minWidth: 120})}
...
<Button
variant="text"
color="inherit"
size="small"
onClick={() => onArchive(row)}
data-testid="action-archive"
sx={{
fontSize: "1.3rem",
fontWeight: "normal",
lineHeight: "2.2rem",
padding: 0,
+ whiteSpace: "nowrap",
color: "rgba(0,0,0,0.56)"
}}
>Also applies to: 238-258
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/mui/table/mui-table.js` around lines 189 - 190, The archive
action column is constrained by tableLayout: "fixed" plus hard 80px
width/minWidth/maxWidth on the TableCell, causing translated "archive/unarchive"
labels to clip; update the TableCell used when onArchive is present (and the
other action cells referenced around lines with onArchive/onDelete) to remove
the maxWidth constraint and give a larger, flexible size (e.g., set width:auto
and a more generous minWidth like 120px) or drop tableLayout: "fixed" for action
columns so the content can expand; change the TableCell props in the mui table
component (the TableCell instances rendered when onArchive and similar action
flags are truthy) accordingly and apply the same fix to the other action column
occurrences noted in the comment.
| size="small" | ||
| onClick={() => onEdit(row)} | ||
| sx={{ padding: 0 }} | ||
| data-testid="action-edit" | ||
| > | ||
| <EditIcon fontSize="large" /> | ||
| <EditIcon fontSize="small" /> | ||
| </IconButton> |
There was a problem hiding this comment.
Edit/Delete IconButtons now have undersized click targets.
size="small" combined with sx={{ padding: 0 }} makes the hit area very small, which is an accessibility blocker for pointer/touch interaction.
Suggested fix
<IconButton
size="small"
onClick={() => onEdit(row)}
- sx={{ padding: 0 }}
+ sx={{ p: 0.5 }}
data-testid="action-edit"
>
<EditIcon fontSize="small" />
</IconButton>
<IconButton
size="small"
onClick={() => handleDelete(row)}
data-testid="action-delete"
- sx={{ padding: 0 }}
+ sx={{ p: 0.5 }}
>
<DeleteIcon fontSize="small"/>
</IconButton>Also applies to: 270-276
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/mui/table/mui-table.js` around lines 225 - 231, The IconButton
elements (e.g., the one with data-testid="action-edit" that calls onEdit(row)
and the similar delete button) have undersized click targets due to size="small"
plus sx={{ padding: 0 }}; update these buttons to provide an accessible hit
target by removing the zero padding and/or the small size and instead apply a
minimum padding (e.g., theme spacing >= 1 or 8px) or use size="medium" so the
clickable area meets touch target guidelines; keep the same icons and handlers
(EditIcon, onEdit(row), delete handler) and adjust the sx styling for both the
edit and delete IconButton instances mentioned in the diff.
| @@ -1,5 +1,5 @@ | |||
| import {getCurrentUserLanguage} from "../utils/methods"; | |||
| import T from "i18n-react"; | |||
| import T from "i18n-react/dist/i18n-react"; | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect i18n-react package.json main/module/exports fields and dist folder contents
fd package.json --search-path node_modules/i18n-react --max-depth 1 --exec cat {}
echo "---dist contents---"
fd . --search-path node_modules/i18n-react/dist --max-depth 1Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 349
🌐 Web query:
i18n-react npm package official import documentation
💡 Result:
For the npm package commonly referred to as “i18n-react” in the React/i18next ecosystem, the official docs correspond to react-i18next. Official import / usage docs (react-i18next) 1) Install - Install react-i18next and i18next with npm. [1][2] 2) Import and initialize i18next + react-i18next (hooks version) - The docs show importing the i18n instance from i18next and initReactI18next from react-i18next, then calling i18n.use(initReactI18next). [3][2] Example (as shown in the docs): - import i18n from "i18next"; - import { initReactI18next } from "react-i18next"; - i18n.use(initReactI18next).init({... }); [3][2] 3) Import the initialized i18n module once at app startup - The docs explicitly say to create a file (e.g., i18n.js) that exports the initialized i18n instance, and then import it in your React entry point (e.g., index.js) so the configuration runs. [3][4] 4) Import i18next instance (t function) outside React components - The docs show that if you need to call t or use the i18next instance outside a React component, you can import the exported i18n/i18next instance (e.g., import i18next from './i18n') and call i18next.t(...). [3][4] Important note about naming - react-i18next’s docs state the documentation is published on react.i18next.com and the general i18next docs are on i18next.com. [5] If you meant a different package literally named “i18n-react” (not react-i18next), tell me the exact npm package name/link and I’ll pull the official import documentation for that specific package.
Citations:
- 1: https://www.npmjs.com/package/react-i18next
- 2: https://react.i18next.com/getting-started
- 3: https://react.i18next.com/guides/quick-start
- 4: https://react.i18next.com/latest
- 5: https://github.com/i18next/react-i18next
🏁 Script executed:
# Search for all imports of i18n-react in the repository
rg "from\s+['\"]i18n-react" --type js --type jsx --type ts --type tsx
# Also check what's currently in src/i18n/i18n.js at line 2
echo "=== Current import in i18n.js ==="
head -5 src/i18n/i18n.jsRepository: OpenStackweb/openstack-uicore-foundation
Length of output: 355
🌐 Web query:
i18n-react npm package
💡 Result:
No npm package named "i18n-react" exists based on searches across npm, GitHub, and general web results[1][2][3]. The query likely refers to the popular react-i18next package, which provides internationalization (i18n) for React apps using the i18next ecosystem[1][3][4][5]. react-i18next is the official React integration for i18next, supporting features like hooks, plurals, interpolation, and SSR[1][4][6][5]. As of 2026-05-08, it has ~11.9M weekly downloads, 379 versions (latest in v17.x from Mar-Apr 2026), MIT license, and requires React >=16.8.0, i18next >=26.0.1[3]. Install: npm i react-i18next i18next[3][4]. Official docs: https://react.i18next.com/[4][6][5]. GitHub: https://github.com/i18next/react-i18next (9.9k stars)[1][7]. Other similar packages include react-intl (2.9M weekly downloads, latest v10.1.5 May 2026)[8] and react-i18nify (20.9k downloads)[9], but react-i18next dominates for i18n in React[3].
Citations:
- 1: https://redirect.github.com/i18next/react-i18next
- 2: https://www.npmjs.com/package/react-i18next/v/14.0.1
- 3: https://www.npmjs.com/package/react-i18next
- 4: https://react.i18next.com/getting-started
- 5: https://react.i18next.com/
- 6: https://react.i18next.com/guides/quick-start
- 7: https://github.com/i18next/react-i18next
- 8: https://www.npmjs.com/package/react-intl
- 9: https://www.npmjs.com/package/react-i18nify
🏁 Script executed:
# Find all files importing from i18n-react (including variations)
rg "i18n-react" --type js --type ts
# Also check if package.json or lock files mention i18n-react
rg "i18n-react" package.json yarn.lock package-lock.json 2>/dev/null || echo "No lock files found with i18n-react"Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 7041
Use the standard i18n-react import instead of the internal /dist/ path.
The codebase currently imports from i18n-react/dist/i18n-react (a deep UMD build path), but many other files successfully import from just i18n-react. The deep import bypasses the package's module resolution and is fragile—any restructuring of the dist folder in a future release will silently break all affected files without a version conflict.
Update this file and the 45+ others throughout the codebase that use the deep path to import from i18n-react directly. This affects src/i18n/i18n.js, src/components/mui/CartButton/index.js, src/components/mui/AuthButton/index.js, src/components/inputs/company-input-v2.js, and many others.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/i18n/i18n.js` at line 2, The import uses a deep path
("i18n-react/dist/i18n-react") which is fragile; replace the deep import with
the package entrypoint by changing the import of T (import T from
"i18n-react/dist/i18n-react") to import from "i18n-react" instead, and run a
repo-wide search/replace for the same deep path to update the ~45 other files
(e.g., occurrences in CartButton, AuthButton, company-input-v2) so all modules
import from "i18n-react" consistently; after updating, run the
build/linter/tests to verify no remaining deep-path references.
d40c7ff to
ec87087
Compare
ref: https://app.clickup.com/t/86b8tt7c7
Summary by CodeRabbit
New Features
UI/Style Enhancements